/*!
 * @file moduleGraphic.hh
 * @brief Moduł odpowiedzialny za rendering
 */

#ifndef __ENGINE_GFX_MODULEGRAPHIC_HH
#define __ENGINE_GFX_MODULEGRAPHIC_HH

#include <iostream>
#include <SDL/SDL_image.h>
#include "engine/pawirr.hh"
#include "engine/moduleBase.hh"

#include "engine/gfx/gfxPrimitives.hh"
#include "engine/gfx/gfxPosteffects.hh"
#include "engine/gfx/gfxEnv.hh"
#include "engine/gfx/gfxParticles.hh"
#include "engine/gfx/gfxDebug.hh"

#include "engine/basic/point2f.hh"
#include "engine/basic/point3f.hh"

/*!
 * @brief Tryby renderowania
 */
enum _render_mode {
	RM_2D, RM_3D, RM_UNSET
};

/*!
 * @brief Moduł odpowiedzialny za grafikę.
 */
class moduleGraphic: public moduleBase {
public:
	/*!
	 * @brief Konstruktor wywołuje initWindow
	 * @return Obiekt
	 */
	moduleGraphic();

	/*!
	 * @brief Ustawianie renderowania
	 * @param mode Tryb do ustawienia
	 */
	void setRenderMode(_render_mode mode);

	void restoreRenderMode();

	/*!
	 * @brief Wyświetlanie wyrenderowanej klatki
	 */
	void flipFrame();

	void clearFrame(color & cl);

	void loadingScreen(std::string label);

	/*!
	 * @brief Ustawienie celu renderowania
	 * @param tx tekstura na której odbędzie się rendering lub NULL
	 */
	void setRenderTarget(texture *tx);

	/*!
	 * @brief Obiekt do malowanie prymitywów
	 */
	gfxPrimitives *_pri;

	/*!
	 * @brief Obiekt do zarządania postefektami
	 */
	gfxPosteffects *_fx;

	/*!
	 * @brief Obiekt do zarządzania zmiennymi środowiskowymi/kamerą
	 */
	gfxEnv *_env;

	/*!
	 * @brief Obiekt do zarządzania cząsteczkami
	 */
	gfxParticles *_pcs;

	gfxDebug *_dbg;

	void init();

	/*!
	 * @brief Rozdzielczość pozioma
	 */
	const int resX;
	const float resXf;

	/*!
	 * @brief Rozdzielczość pionowa
	 */
	const int resY;
	const float resYf;

	/*!
	 * @brief Czy isFullscreen?
	 */
	const bool isFullscreen;

private:
	/*!
	 * @brief Inicjaliacja okna
	 */
	void initWindow();

	/*!
	 * @brief Inicjalizacja opengl
	 */
	void initOpengl();

	/*!
	 * @brief Ekran po którym przebiega malowanie
	 */
	SDL_Surface *screenSdl;

	/*!
	 * @brief Czy wyświetlać siatkę siatka
	 */
	int *isPolygonMesh;

	_render_mode rmPrev;
	_render_mode rmCurrent;
};

#else
class moduleGraphic;
#endif
